package com.mms.utsc.smartnet;

import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ExecutionException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.SQLException;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.Toast;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.LinearLayout;
import android.widget.TextView;

public class AnnouncementsActivity extends Activity implements OnClickListener, OnGroupClickListener, android.content.DialogInterface.OnClickListener {

	ArrayList<Announcement> announcements;
	ExpandableListView menuList;
	View openLayout;
	Announcement currViewingAnnouncement;
	DBHandler db;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.announcement);

		// get announcements from database
		ProgressDialog dialog = ProgressDialog.show(this, null, "Loading - Please wait...");
		db = new DBHandler(dialog, this);
		try {
			db.updateAnnouncements();
		} catch (Exception e) {
			Toast.makeText(this, "Cannot download announcements.", Toast.LENGTH_SHORT).show();
		}
		announcements = db.getLocalDBHandler().getAllAnnouncements(null);

		LinearLayout parentLayout = (LinearLayout) findViewById(R.id.llAnnouncement);
		menuList = new ExpandableListView(AnnouncementsActivity.this);
		menuList.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		menuList.setAdapter(new AnnouncementListAdapter(AnnouncementsActivity.this, R.layout.announcement_list_item, R.layout.announcement_list_subitem, this.announcements));
		menuList.setId(R.id.elvAnnouncement_menuList);
		menuList.setDividerHeight(20);
		menuList.setOnGroupClickListener(this);
		parentLayout.addView(menuList);

		// set the indicator arrow to the right of the ExpandableListView
		Display myDisplay = getWindowManager().getDefaultDisplay();
		Point size = new Point();
		myDisplay.getSize(size);
		int width = size.x;
		menuList.setIndicatorBounds(width - 50, width);
		db.close();
		dialog.dismiss();
	}

	/**
	 * This method is called when a button in the ExpandableListView is clicked.
	 */
	public void onClick(View v) {
		// TODO Auto-generated method stub
		// v is the button that's clicked
		currViewingAnnouncement = (Announcement) v.getTag(R.id.TAG_KEY_ANNOUNCEMENT);
		switch (v.getId()) {
		case R.id.bAnnouncementListItemDetails:
			// details button is clicked
			AlertDialog alert = new AlertDialog.Builder(AnnouncementsActivity.this).create();

			alert.setCancelable(true);
			alert.setCanceledOnTouchOutside(true);
			alert.setTitle(currViewingAnnouncement.getTitleText());
			alert.setMessage(currViewingAnnouncement.getContent());

			alert.setButton(AlertDialog.BUTTON_POSITIVE, "Delete", this);
			if (currViewingAnnouncement.isImportant()) {
				alert.setButton(AlertDialog.BUTTON_NEUTRAL, "Mark as Unimportant", this);
			} else {
				alert.setButton(AlertDialog.BUTTON_NEUTRAL, "Mark as Important", this);
			}
			alert.show();
			break;
		case R.id.bAnnouncementListItemDelete:
			// delete button is clicked
			deleteAnnouncement(currViewingAnnouncement);
			break;
		case R.id.bAnnouncementListItemImportant:
			// important button is clicked
			changeImportance(currViewingAnnouncement, !currViewingAnnouncement.isImportant());
			break;
		}
	}

	/**
	 * onClick from AlertDialog
	 */
	public void onClick(DialogInterface dialog, int which) {
		// TODO Auto-generated method stub
		if (which == AlertDialog.BUTTON_POSITIVE) {
			// delete announcement
			deleteAnnouncement(currViewingAnnouncement);
			Parcelable prevState = menuList.onSaveInstanceState();
			menuList.setAdapter(new AnnouncementListAdapter(AnnouncementsActivity.this, R.layout.announcement_list_item, R.layout.announcement_list_subitem, this.announcements));
			menuList.onRestoreInstanceState(prevState);
		} else if (which == AlertDialog.BUTTON_NEUTRAL) {
			// mark as important or unimportant
			changeImportance(currViewingAnnouncement, !currViewingAnnouncement.isImportant());
		}

	}

	private void deleteAnnouncement(Announcement toDelete) {
		announcements.remove(toDelete);
		db.openLocalDBHandler();
		db.getLocalDBHandler().deleteAnnouncementEntry(toDelete.getID());
		db.close();
	}

	private void changeImportance(Announcement announcement, boolean important) {
		announcements.remove(announcement);
		announcement.setIsImportant(important);
		announcements.add(announcement);
		db.openLocalDBHandler();
		db.getLocalDBHandler().updateAnnouncementEntry(announcement.getID(), announcement);
		db.close();
	}

	// onClick of the ExpandableListView
	public boolean onGroupClick(ExpandableListView elv, View view, int position, long id) {
		// TODO Auto-generated method stub
		return false;
	}

	class AnnouncementListAdapter extends BaseExpandableListAdapter {
		private LayoutInflater inflater = null;
		int groupLayoutID = -1, childLayoutID = -1;
		private AnnouncementsActivity parentActivity = null;
		ArrayList<ArrayList<Announcement>> menuList;

		public AnnouncementListAdapter(AnnouncementsActivity parentActivity, int groupLayoutID, int childLayoutID, ArrayList<Announcement> allAnnouncements) {
			this.parentActivity = parentActivity;
			this.groupLayoutID = groupLayoutID;
			this.childLayoutID = childLayoutID;
			this.menuList = new ArrayList<ArrayList<Announcement>>();
			this.inflater = (LayoutInflater) parentActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			ArrayList<Announcement> typeList = new ArrayList<Announcement>();

			for (Announcement.AnnouncementType type : Announcement.AnnouncementType.values()) {
				typeList = Announcement.filterType(allAnnouncements, type);
				if (typeList == null)
					continue;
				this.menuList.add(typeList);
			}
		}

		public Announcement getChild(int groupPosition, int childPosition) {
			return this.menuList.get(groupPosition).get(childPosition);
		}

		public long getChildId(int groupPosition, int childPosition) {
			return this.menuList.get(groupPosition).get(childPosition).getID();
		}

		public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View view = convertView;
			if (convertView == null)
				view = inflater.inflate(this.childLayoutID, null);
			Announcement toInflate = this.getChild(groupPosition, childPosition);

			Button bDetails = (Button) view.findViewById(R.id.bAnnouncementListItemDetails);
			// tag is an announcement object
			bDetails.setTag(R.id.TAG_KEY_ANNOUNCEMENT, this.getChild(groupPosition, childPosition));
			bDetails.setTag(R.id.TAG_KEY_CHILDPOSITION, childPosition);
			bDetails.setOnClickListener(parentActivity);
			Button bDelete = (Button) view.findViewById(R.id.bAnnouncementListItemDelete);
			bDelete.setTag(R.id.TAG_KEY_ANNOUNCEMENT, this.getChild(groupPosition, childPosition));
			bDelete.setTag(R.id.TAG_KEY_CHILDPOSITION, childPosition);
			bDelete.setOnClickListener(parentActivity);
			Button bImportant = (Button) view.findViewById(R.id.bAnnouncementListItemImportant);
			bImportant.setTag(R.id.TAG_KEY_ANNOUNCEMENT, this.getChild(groupPosition, childPosition));
			bImportant.setTag(R.id.TAG_KEY_CHILDPOSITION, childPosition);
			Drawable importanceImg = null;
			Bitmap bitmap = null;
			double widHeiRatio;
			final int targetHeight = 30;
			if (toInflate.isImportant()) {
				importanceImg = getResources().getDrawable(R.drawable.important);
			} else {
				importanceImg = getResources().getDrawable(R.drawable.unimportant);
			}

			bitmap = ((BitmapDrawable) importanceImg).getBitmap();
			widHeiRatio = bitmap.getWidth() / bitmap.getHeight();
			importanceImg = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, (int) (widHeiRatio * targetHeight), targetHeight, true));

			bImportant.setCompoundDrawablesWithIntrinsicBounds(importanceImg, null, null, null);
			bImportant.setOnClickListener(parentActivity);

			TextView mainText = (TextView) view.findViewById(R.id.tvAnnouncementListItemMain);
			mainText.setText(toInflate.getTitleText());
			TextView subText = (TextView) view.findViewById(R.id.tvAnnouncementListItemSub);
			subText.setText(toInflate.getContent());

			return view;
		}

		public int getChildrenCount(int groupPosition) {
			return this.menuList.get(groupPosition).size();
		}

		public ArrayList<Announcement> getGroup(int groupPosition) {
			return this.menuList.get(groupPosition);
		}

		public int getGroupCount() {
			return this.menuList.size();
		}

		public long getGroupId(int groupPosition) {
			return groupPosition;
		}

		public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View view = convertView;
			if (convertView == null)
				view = inflater.inflate(this.groupLayoutID, null);

			TextView typeText = (TextView) view.findViewById(R.id.tvAnnouncementListGroup);
			// The title of each announcement type
			typeText.setText(menuList.get(groupPosition).get(0).getTypeStr() + " (" + menuList.get(groupPosition).size() + ")");
			typeText.setBackgroundColor(Color.rgb(100, 149, 237));
			return view;
		}

		public boolean hasStableIds() {
			// TODO don't know what this does
			return false;
		}

		public boolean isChildSelectable(int groupPosition, int childPosition) {
			// TODO may want to modify this later
			return true;
		}

	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		db.getLocalDBHandler().open();
		super.onResume();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		db.getLocalDBHandler().close();
		super.onStop();
	}

}
